<template>
    <div class="page-container">
        <!-- 回到顶部 -->
        <el-backtop :right="100" :bottom="100" ref="refBackTop" :visibility-height="100" target=".el-main"></el-backtop>
        <!-- 头部 -->
        <div class="page-filter">
            <el-select v-model="filterAdvice.status" class="m-2" placeholder="请选择广告类型" clearable>
                <el-option v-for="item in adStatusMap" :key="item.value" :label="item.name" :value="item.value" />
            </el-select>
            <el-select v-model="filterAdvice.type" class="m-2" placeholder="请选择类型" clearable>
                <el-option v-for="item in adTypeMap" :key="item.value" :label="item.name" :value="item.value" />
            </el-select>
            <el-button :icon="Search" type="primary" @click="getAdviceList">查找</el-button>
            <el-button :icon="Plus" type="primary" @click="handleAddOpenDialog" v-permission="'promotion:advert:delete'">添加</el-button>
        </div>
        <!-- 列表数据 -->

        <div class="page-table">
            <el-table :data="adviceList" border style="width: 100%" stripe v-loading="loading" element-loading-text="拼命加载中...">
                <el-table-column prop="id" label="广告ID" align="center" />
                <el-table-column prop="title" label="广告标题" align="center" />
                <el-table-column prop="imgUrl" label="广告图片" align="center">
                    <template #default="scope">
                        <el-popover trigger="hover" placement="right" :width="180"
                            v-if="scope.row.imgUrl && scope.row.imgUrl !== virtual_pic">
                            <template #reference>
                                <el-image style="width: 60px; height: 60px" :src="scope.row.imgUrl" fit="cover" />
                            </template>
                            <el-image style="width: 150px; height: 150px" :src="scope.row.imgUrl" fit="cover" />
                        </el-popover>
                        <el-tag v-else type="info">类型无需图片</el-tag>
                    </template>
                </el-table-column>
                <el-table-column prop="type" label="广告类型" align="center">
                    <template #default="scope">
                        <el-tag>{{ findTypeName(scope.row.type) }}</el-tag>
                    </template>
                </el-table-column>
                <el-table-column prop="status" label="广告状态" align="center">
                    <template #default="scope">
                        <el-tag type="danger" v-if="scope.row.status === 0">冻结</el-tag>
                        <el-tag type="success" v-else>激活</el-tag>
                    </template>
                </el-table-column>
                <el-table-column prop="unionType" label="关联类型" align="center">
                    <template #default="scope">
                        <template v-for="item in adUnionTypeMap" :key="item.value">
                            <el-tag type="warning" v-if="item.value === scope.row.unionType">{{ item.name }}</el-tag>
                        </template>
                    </template>
                </el-table-column>
                <el-table-column prop="unionValue" label="关联值【ID】" align="center" />
                <el-table-column prop="gmtCreate" label="创建时间" align="center">
                    <template #default="scope">
                        {{ moment(scope.row.gmtCreate).format('YYYY-MM-DD hh:mm') }}
                    </template>
                </el-table-column>
                <el-table-column label="操作" align="center">
                    <template #default="scope">
                        <el-button type="primary" @click="handleEdit(scope.row)" v-permission="'promotion:advert:delete'">编辑</el-button>
                        <el-button type="danger" @click="handleDeleteAdvice(scope.row)" v-permission="'promotion:advert:edit'">删除</el-button>
                    </template>
                </el-table-column>
            </el-table>
        </div>
        <!-- 分页 -->
        <div style="overflow: hidden;">
            <Pagination v-bind="pagination" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
        </div>
        <!-- 对话框 -->
        <el-dialog v-model="dialogFormVisible" :title="dialogTitle" @close="handleCloseDialog">
            <el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" label-width="120px">
                <el-form-item label="广告标题" prop="title">
                    <el-input v-model="ruleForm.title" placeholder="请输入广告标题" clearable/>
                </el-form-item>
                <el-form-item label="广告类型" prop="type">
                    <el-select v-model="ruleForm.type" class="m-2" placeholder="请选择类型" @change="hanlderClearImg" clearable>
                        <el-option v-for="item in adTypeMap" :key="item.value" :label="item.name" :value="item.value" />
                    </el-select>
                </el-form-item>
                <el-form-item label="广告图片" v-show="adTypeMap.find(val => val.value === ruleForm.type)?.picRequire" style="width:100%;"  id="uploadImg" :style="{ background: ruleForm.color }">
                    <el-upload class="avatar-uploader" :action="uploadPath" :headers="headers" :show-file-list="false"
                        :on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload">
                        <img v-if="ruleForm.imgUrl" :src="ruleForm.imgUrl" class="avatar" width="178" />
                        <el-icon v-else class="avatar-uploader-icon">
                            <Plus />
                        </el-icon>
                    </el-upload>
                </el-form-item>
                <el-form-item label="广告状态" prop="status">
                    <el-switch v-model="ruleForm.status" :active-value="1" :inactive-value="0" />
                </el-form-item>
                <el-form-item label="关联类型" prop="unionType">
                    <el-select v-model="ruleForm.unionType" class="m-2" placeholder="点击时跳转到目标"
                        @change="handleClearUnionType" clearable>
                        <el-option v-for="item in typeFindUnionType(ruleForm.type)" :key="item.value" :label="item.name"
                            :value="item.value" />
                    </el-select>
                </el-form-item>
                <el-form-item label="商品" prop="unionValue" v-if="ruleForm.unionType === 1">
                    <el-cascader :options="spuBigTree" v-model="ruleForm.unionValue"
                        :props="{ emitPath: false, value: 'id' }" placeholder="关联至商品" filterable clearable/>
                </el-form-item>
                <el-form-item label="类目" prop="unionValue" v-if="ruleForm.unionType === 2">
                    <el-cascader :options="options" v-model="ruleForm.unionValue"
                        :props="{ emitPath: false, value: 'id', label: 'title', children: 'childrenList' }"
                        placeholder="关联至类目" filterable clearable/>
                </el-form-item>
                <el-form-item label="关键字" prop="unionValue" v-if="ruleForm.unionType === 3">
                    <el-input v-model="ruleForm.unionValue"></el-input>
                </el-form-item>
                <el-form-item label="功能页面" prop="unionValue" v-if="ruleForm.unionType === 4">
                    <el-select v-model="ruleForm.unionValue" class="m-2" placeholder="请选择一个功能页面">
                        <el-option v-for="item in functionPages" :key="item.value" :label="item.name" :value="item.value" />
                    </el-select>
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" @click="submitForm(ruleFormRef)">
                        确定
                    </el-button>
                    <el-button @click="resetForm(ruleFormRef)">取消</el-button>
                </el-form-item>
            </el-form>
        </el-dialog>
    </div>
</template>
<script lang="ts" setup>
import { ClassPagination, ClassAdvice } from "#/index";
import Pagination from "@/components/pagination/Pagination.vue";
import { post, host } from "@/utils/http";
import { Plus, Search } from "@element-plus/icons-vue";
import { ElMessage, ElMessageBox } from "element-plus";
import { computed, nextTick, onMounted, reactive, ref } from "vue";
import moment from "moment";
import cookies from 'js-cookie'
import type { FormInstance, FormRules } from 'element-plus'
import type { UploadProps } from 'element-plus'
import {canvasImgColor} from '@/utils/close'

//回到顶部
const refBackTop = ref()
//显示加载
const loading = ref(false)
//上传文件的路径地址
const uploadPath = host + "/upload/admin"
//文件上传请求头
const headers = computed(() => {
    return {
        ADMINTOKEN: cookies.get("adminToken")
    }
})
//form表单节点
const ruleFormRef = ref<FormInstance>()
//form表单对象
const ruleForm = reactive({
    ...new ClassAdvice()
})
//form表单校验规则
const rules = reactive<FormRules>({
    title: [{ required: true, message: '请输入广告标题', trigger: 'blur' }],
    type: [{ required: true, message: '请输入广告类型', trigger: 'change' }],
    status: [{ required: true, message: '请输入广告标题', trigger: 'change' }],
    unionType: [{ required: true, message: '请输入关联类型', trigger: 'change' }],
    unionValue: [{ required: true, message: '请输入关联内容', trigger: 'change' }],

})

//分页对象
const pagination = reactive(new ClassPagination())
//广告列表数据
const adviceList = ref([{} as ClassAdvice])

//对话框主题
const dialogTitle = ref('')
//商品数据
const spuBigTree = ref([])
//类目数据
const options = ref()
//对话框是否显示
const dialogFormVisible = ref(false)
//广告状态
const adStatusMap = reactive([{ value: 0, name: '冻结' }, { value: 1, name: '激活' }])
//广告类型
const adTypeMap = reactive([
    { value: 1, unionTypes: [1, 2, 3, 4], picRequire: true, name: '轮播' },
    { value: 2, unionTypes: [2], picRequire: true, name: '分类精选' },
    { value: 3, unionTypes: [1, 2, 3, 4], picRequire: true, name: '横幅' },
    { value: 4, unionTypes: [1, 2, 3, 4], picRequire: true, name: '首页轮播下5按钮' },
    { value: 6, unionTypes: [1, 2, 3, 4], picRequire: false, name: '公告' },
    { value: 9, unionTypes: [1], picRequire: false, name: '商品推荐' }
])
//默认图片
const virtual_pic = "https://www.baidu.com/img/flexible/logo/pc/result.png"
//广告关联类型
const adUnionTypeMap = reactive([
    { value: 1, name: '商品' },
    { value: 2, name: '类目' },
    { value: 3, name: '关键字' },
    { value: 4, name: '功能页面' }
])
//功能页面
const functionPages = reactive([
    { value: "/pages/product/groupshop", name: '团购列表' },
    { value: "/pages/coupon/list", name: "优惠券列表" }
])
//添加修改对象
const addAdvice = computed(() => {
    let tempobj = new ClassAdvice()
    Object.assign(tempobj, { ...ruleForm, adId: ruleForm.id })
    if (tempobj.type === 6 || tempobj.type === 9) {
        tempobj.imgUrl = virtual_pic;
    }
    return tempobj
})
/**
 * 通过type类型值找到关联类型
 * @param val type类型值
 */
function typeFindUnionType(val: number | undefined) {
    let index = adTypeMap.findIndex(item => item.value === val)
    let arr: { value: number; name: string; }[] = []
    if (adTypeMap[index]) {
        adTypeMap[index].unionTypes.forEach(item => {
            let bol = adUnionTypeMap.findIndex(data => data.value === item)
            if (bol != -1) {
                arr.push(adUnionTypeMap[bol])
            }
        })
    }
    return arr
}
//广告过滤对象
const filterAdvice = reactive({
    type: undefined,
    status: undefined
})

onMounted(() => {
    getAdviceList()
    getSpuBigTree()
    getCategory()
})
/**
 * 找到广告类型中的name
 * @param val 类型的value值
 */
function findTypeName(val: number) {
    let str = ''
    let index = adTypeMap.findIndex(data => data.value === val)
    if (index != -1) {
        str = adTypeMap[index].name
    }
    return str
}

/**
 * 获取广告的数据列表
 */
function getAdviceList() {
    loading.value = true
    const data = {
        _gp: 'admin.advert', _mt: 'list',
        pageNo: pagination.currentPage, limit: pagination.pageSize, ...filterAdvice
    }
    post(data).then(res => {
        console.log(res)
        const { data, errno, errmsg } = res
        if (200 === errno) {
            const { items, total } = data
            adviceList.value = items
            pagination.total = total
            nextTick(() => {
                loading.value = false
                refBackTop.value.$el.click?.()
            })
        } else {
            ElMessage.error(errmsg)
        }
    })
}
/**
 * 获取商品树数据
 */
function getSpuBigTree() {
    const data = { _gp: 'admin.product', _mt: 'getSpuBigTree' }
    post(data).then(res => {
        console.log(res)
        const { data, errmsg, errno } = res
        if (200 === errno) {
            spuBigTree.value = filterData(data)
        } else {
            ElMessage.error(errmsg)
        }
    })
}
/**
 * 获取分类树
 */
function getCategory() {
    const data = { _gp: 'admin.category', _mt: 'categoryTree' }
    post(data).then(res => {
        const { data, errno } = res
        if (200 === errno) {
            console.log(data)
            options.value = filterData(data)
        } else {
            ElMessage.error('获取分类失败')
        }
    })
}
/**
 * 过滤树数据，不能选择第二层
 * @param arr 数组
 */
function filterData(arr: []) {
    arr.forEach((item: any) => {
        if (item.childrenList) {
            filterData(item.childrenList)
        } else {
            if (item.level < 2) {
                item.disabled = true
            }
        }
    })
    return arr
}
/**
 * 改变一页多少行,防止多次请求
 * @param value 一页多少行
 */
function handleSizeChange(value: number) {
    let tempCurrent = Math.ceil(pagination.total / value)
    if (tempCurrent < pagination.currentPage) {
        pagination.currentPage = tempCurrent
    }
    pagination.pageSize = value
    getAdviceList()
}

/**
 * 改变当前页
 * @param value 当前页数
 */
function handleCurrentChange(value: number) {
    pagination.currentPage = value
    getAdviceList()
}
/**
 * 打开添加对话框
 */
function handleAddOpenDialog() {
    dialogFormVisible.value = true
    dialogTitle.value = '创建'
}
/**
 * 添加修改提交
 * @param formEl form表单节点
 */
const submitForm = async (formEl: FormInstance | undefined) => {
    if (!formEl) return
    await formEl.validate((valid, fields) => {
        if (valid) {
            let mt = dialogTitle.value == '创建' ? 'create' : 'edit'
            console.log(addAdvice.value)
            const data = { _gp: 'admin.advert', _mt: mt, ...addAdvice.value }
            post(data).then(res => {
                const { data, errmsg, errno } = res
                if (200 === errno) {
                    dialogFormVisible.value = false
                    ElMessage.success(dialogTitle.value+'成功')
                    getAdviceList()
                } else {
                    ElMessage.error(errmsg)
                }
            })
        } else {
            console.log('error submit!', fields)
        }
    })
}
/**
 * 对话框取消
 * @param formEl form表单节点
 */
const resetForm = (formEl: FormInstance | undefined) => {
    if (!formEl) return
    formEl.resetFields()
    dialogFormVisible.value = false
}
/**
 * 关闭对话框回调函数
 */
function handleCloseDialog() {
    ruleFormRef.value?.resetFields()
    Object.assign(ruleForm, new ClassAdvice())
}
/**
 * 打开编辑对话框
 * @param row 当前行对象
 */
function handleEdit(row: ClassAdvice) {
    dialogTitle.value = '编辑'
    if (row.unionType === 1 || row.unionType === 2) {
        row.unionValue = Number(row.unionValue)
    }
    if(row.type === 6 || row.type === 9){
        row.imgUrl = ""
    }
    Object.assign(ruleForm, row)
    dialogFormVisible.value = true
}
/**
 * 删除
 * @param row 当前行对象
 */
function handleDeleteAdvice(row: ClassAdvice) {
    const data = { _gp: 'admin.advert', _mt: 'delete', type: row.type, adId: row.id }
    ElMessageBox.confirm(
        '是否删除该数据?',
        '删除',
        {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning',
        }
    ).then(() => {
        post(data).then(res => {
            const { data, errmsg, errno } = res
            if (200 === errno) {
                ElMessage.success('删除成功')
                getAdviceList()
            } else {
                ElMessage.success(errmsg)
            }
        })
    }).catch(() => {
        ElMessage({
        type: 'info',
        message: '取消删除',
      })
    })
}
/**
 * 点击关联类型时，清空关联ID
 */
function handleClearUnionType() {
    ruleForm.unionValue = undefined
}
function hanlderClearImg(){
    ruleForm.unionType=undefined
    ruleForm.imgUrl = ""
    ruleForm.color = ""
}
/**
 * 图片上传成功回调
 */
const handleAvatarSuccess: UploadProps['onSuccess'] = (response) => {
    ruleForm.imgUrl = response.url
    canvasImgColor(ruleForm.imgUrl, (e: string) => {//第一个参数是图片路径
        ruleForm.color = e
  })

}
/**
 * 图片验证
 */
const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
    if (rawFile.type !== 'image/jpeg' && rawFile.type !== 'image/png' && rawFile.type !== 'image/webp') {
        ElMessage.error('只支持JPG文件!')
        return false
    } else if (rawFile.size / 1024 / 1024 > 2) {
        ElMessage.error('文件大小不能超过2MB!')
        return false
    }
    return true
}
</script>
<style lang="less">
.page-filter {
    display: flex;

    .el-select {
        margin-right: 10px;
    }
}
.avatar-uploader .avatar {
  width: 178px;
  height: 178px;
  display: block;
}
.avatar-uploader .el-upload {
    border: 1px dashed var(--el-border-color);
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
    transition: var(--el-transition-duration-fast);
}

.avatar-uploader .el-upload:hover {
    border-color: var(--el-color-primary);
}

.el-icon.avatar-uploader-icon {
    font-size: 28px;
    color: #8c939d;
    width: 178px;
    height: 178px;
    text-align: center;
}
</style>